package com.gjsrmyy.edi.service;

import com.gjsrmyy.edi.client.WebService;
import com.gjsrmyy.edi.client.WebServiceLocator;
import com.gjsrmyy.edi.client.WebServiceSoap;
import com.gjsrmyy.edi.config.MapperFactory;
import com.gjsrmyy.edi.constant.WebserviceParam;
import com.gjsrmyy.edi.entity.*;
import com.gjsrmyy.edi.mapper.EdiMapper;
import com.gjsrmyy.edi.utils.JAXBUtil;
import lombok.extern.java.Log;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Log
public class ClientServiceImpl implements ClientService {
    private EdiMapper ediMapper = MapperFactory.Edi.createMapper(EdiMapper.class);

    public void uploadGoodsDirOfDrugs() throws Exception {
        List<String> xml = ediMapper.loadGoodsDirOfDrugs();
        String resp = uploadOfDrugs(xml, "his_spml");
        log.info(resp);
    }

    @Override
    public void uploadGoodsDirOfConsumables() throws Exception {
        List<String> xml = ediMapper.loadGoodsDirOfConsumables();
        String resp = uploadOfConsumables(xml, "his_spml");
//        ResultBean bean = JAXBUtil.convertToJavaBean(resp,ResultBean.class);
        log.info(resp);
    }

    @Override
    public void uploadDepartmentOfDrugs() throws Exception {
        List<String> xml = ediMapper.loadDepartmentDirOfDrugs();
        String resp = uploadOfDrugs(xml, "his_bmml");
        log.info(resp);
    }

    @Override
    public void uploadDepartmentOfConsumables() throws Exception {
        List<String> xml = ediMapper.loadDepartmentDirOfConsumables();
        String resp = uploadOfConsumables(xml, "his_bmml");
        log.info(resp);
    }


    @Override
    public void uploadSupplierDirOfDrugs() throws Exception {
        List<String> xml = ediMapper.loadSupplierDirOfDrugs();
        String resp = uploadOfDrugs(xml, "his_gysml");
        log.info(resp);
    }

    @Override
    public void uploadSupplierDirOfConsumables() throws Exception {
        List<String> xml = ediMapper.loadSupplierDirOfConsumables();
        String resp = uploadOfConsumables(xml, "his_gysml");
        log.info(resp);
    }

    @Override
    public void uploadStaffDirOfDrugs() throws Exception {
        List<String> xml = ediMapper.loadStaffDirOfDrugs();
        String resp = uploadOfDrugs(xml, "his_ryml");
        log.info(resp);
    }

    @Override
    public void uploadStaffDirOfConsumables() throws Exception {
        List<String> xml = ediMapper.loadStaffDirOfConsumables();
        String resp = uploadOfConsumables(xml, "his_ryml");
        log.info(resp);
    }

    @Override
    public void uploadProcurementPlanOfDrugs() throws Exception {
        List<String> xml = ediMapper.loadProcurementPlanOfDrugs();
        if (xml != null && xml.size() != 0) {
            String resp = uploadOfDrugs(xml, "his_cgjh");
            log.info(resp);
        }
    }

    @Override
    public void uploadProcurementPlanOfConsumables() throws Exception {
        List<String> xml = ediMapper.loadProcurementPlanOfConsumables();
        if (xml != null && xml.size() != 0) {
            String resp = uploadOfConsumables(xml, "his_cgjh");
            log.info(resp);
        }
    }

    @Override
    public void uploadRegistrationOfDrugs() throws Exception {
        List<String> xml = ediMapper.loadRegistrationOfDrugs();
        if (xml != null && xml.size() != 0) {
            String resp = uploadOfDrugs(xml, "his_rkjl");
            log.info(resp);
        }
    }

    @Override
    public void uploadRegistrationOfConsumables() throws Exception {
        List<String> xml = ediMapper.loadRegistrationOfConsumables();
        if (xml != null && xml.size() != 0) {
            String resp = uploadOfConsumables(xml, "his_rkjl");
            log.info(resp);
        }
    }

    @Override
    public void outputOfConsumables() throws Exception {
        String resp = outPutOfConsumables(null, "EDI_shjl_cshis");
        log.info(resp);
        Map<String, List<OutPutEntity>> map = formatOutPut(resp);
        if (map != null && map.size() != 0) {
            //遍历map,取每个map下list中的第一条数据写入WZ_CG01,list下每条数据写入WZ_CG02
            for (String key : map.keySet()) {
                String billNo = produceBillNo();        // 单据编号
                String roamNo = produceRoamNo();        // 流转单号

                List<OutPutEntity> list = map.get(key);
                ediMapper.insertProcurement(billNo, roamNo, list.get(0).getYy_gysdm(), list.get(0).getYy_ysrdm(), list.get(0).getYy_ysrmc());

                for (OutPutEntity entity : list) {
                    OutGoods goods = ediMapper.queryGoodsInfo(entity.getYy_spdm());
                    String detailedNo = produceDetailedNo();        // 明细编号
                    String stockNo = produceStockNo();              // 库存识别

                    // 写入WZ_CG02
                    ediMapper.insertDetailed(detailedNo, billNo, entity.getYy_spdm(), entity.getYy_csdm(), entity.getPh(), entity.getDj(), goods.getRetailPrice(), entity.getYssl(),
                            goods.getUnit(), goods.getPacking(), stockNo, goods.getWholesalePrice(),entity.getFhdh());
                }
            }
        }
    }

    @Override
    public void outputOfDrugs() throws Exception {
        String resp = outPutOfDrugs(null, "EDI_shjl_cshis");
        log.info(resp);
        Map<String, List<OutPutEntity>> map = formatOutPut(resp);
        Map<String, List<Map<String, List<OutPutEntity>>>> mapHashMap = new HashMap<>();

        List<OutPutEntity> listX ;
        List<OutPutEntity> listZ ;
        if (map != null && map.size() != 0) {

            Map<String, List<OutPutEntity>> mapX;
            Map<String, List<OutPutEntity>> mapZ;
            List<Map<String, List<OutPutEntity>>> listMapX = new ArrayList<>();
            List<Map<String, List<OutPutEntity>>> listMapZ = new ArrayList<>();

            mapHashMap.put("1", listMapX);
            mapHashMap.put("2", listMapZ);

            //遍历map,取每个map下list中的第一条数据写入YK_RK01,list下每条数据写入YK_RK02
            for (String key : map.keySet()) {
                List<OutPutEntity> list = map.get(key);
                mapX = new HashMap<>();
                mapZ = new HashMap<>();
                listX = new ArrayList<>();
                listZ = new ArrayList<>();

                for (OutPutEntity entity : list) {
                    if (ediMapper.checkFlag(entity.getYy_spdm()).equals("1")) {
                        listX.add(entity);
                    } else if (ediMapper.checkFlag(entity.getYy_spdm()).equals("2")) {
                        listZ.add(entity);
                    }
                }
                mapX.put(key, listX);
                mapZ.put(key, listZ);
                mapHashMap.get("1").add(mapX);
                mapHashMap.get("2").add(mapZ);
            }
        }

        for (String key : mapHashMap.keySet()){
            if (key.equals("1")) {// 西药
                for (Map<String, List<OutPutEntity>> listMap : mapHashMap.get(key)) {
                    for (String key_1 : listMap.keySet()){
                        //写RK01
                        String intoNo = ediMapper.produceIntoNo(key);
                        String supplier = ediMapper.querySupplier(key,listMap.get(key_1).get(0).getYy_gysmc());
                        ediMapper.insertWarehousing(key,intoNo,supplier,listMap.get(key_1).get(0).getYy_ysrdm());
                        for (OutPutEntity entity : listMap.get(key_1)){
                            // 写入数据到RK02
                            String stockNo = ediMapper.produceIdentityNoOfDrugs("YK_KCMX");
                            String recognitionNo = ediMapper.produceIdentityNoOfDrugs("YK_RK02");
                            OutGoods goods = ediMapper.queryOutGoodsOfDrugs(entity.getYy_spdm(),entity.getYy_csdm());

                            ediMapper.insertWarehousingDetailed(recognitionNo,key,intoNo,entity.getYy_spdm(),entity.getYy_csdm(),entity.getPh(),entity.getXq(),goods.getWholesalePrice(),goods.getRetailPrice(),stockNo,entity.getYssl(),goods.getPurchasePrice(),goods.getBaseFlag(),entity.getFhdh());
                        }
                    }
                }
            }else if (key.equals("2")){// 中药
                for (Map<String, List<OutPutEntity>> listMap : mapHashMap.get(key)) {
                    for (String key_2 : listMap.keySet()){
                        //写入RK01
                        String intoNo = ediMapper.produceIntoNo(key);
                        String supplier = ediMapper.querySupplier(key,listMap.get(key_2).get(0).getYy_gysmc());
                        ediMapper.insertWarehousing(key,intoNo,supplier,listMap.get(key_2).get(0).getYy_ysrdm());
                        for (OutPutEntity entity : listMap.get(key_2)){
                            String recognitionNo = ediMapper.produceIdentityNoOfDrugs("YK_RK02");
                            String stockNo = ediMapper.produceIdentityNoOfDrugs("YK_KCMX");
                            OutGoods goods = ediMapper.queryOutGoodsOfDrugs(entity.getYy_spdm(),entity.getYy_csdm());

                            ediMapper.insertWarehousingDetailed(recognitionNo,key,intoNo,entity.getYy_spdm(),entity.getYy_csdm(),entity.getPh(),entity.getXq(),goods.getWholesalePrice(),goods.getRetailPrice(),stockNo,entity.getYssl(),goods.getPurchasePrice(),goods.getBaseFlag(),entity.getFhdh());

                        }
                    }
                }
            }
        }

    }


    /**
     * 通用上传方法
     *
     * @param xml
     * @param tableName
     * @return
     * @throws Exception
     */
    private String uploadOfDrugs(List<String> xml, String tableName) throws Exception {
        String msgXml = formatXml(xml);
        byte[] params = paramOfDrugs(tableName, msgXml);
        String resp = invoke("InPut", params);
        return resp;
    }

    private String uploadOfConsumables(List<String> xml, String tableName) throws Exception {
        String msgXml = formatXml(xml);
        byte[] params = paramOfConsumables(tableName, msgXml);
        String resp = invoke("InPut", params);
        return resp;
    }


    private String outPutOfConsumables(List<?> param, String tableName) throws Exception {
        byte[] params = paramOfConsumables(tableName, "");
        String resp = invoke("OutPut", params);
        return resp;
    }

    private String outPutOfDrugs(List<?> param, String tableName) throws Exception {
        byte[] params = paramOfDrugs(tableName, "");
        String resp = invoke("OutPut", params);
        return resp;
    }

    private String invoke(String method, byte[] param) {
        byte[] result = null;
        String resultStr = "";
        try {
            WebService webService = new WebServiceLocator();
            WebServiceSoap webServiceSoap = webService.getWebServiceSoap();

            switch (method) {
                case "InPut": {
                    result = webServiceSoap.inPut(param);
                }
                break;
                case "OutPut": {
                    result = webServiceSoap.outPut(param);
                }
                break;
                default:
                    break;

            }
            resultStr = new String(result, "gb2312");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultStr;
    }

    /**
     * 格式化xml
     *
     * @param list
     * @return
     */
    private String formatXml(List<String> list) {
        if (list.size() == 0) return "";
        String msgXml = "<msg>";
        try {
            for (String xml : list) {
                msgXml += xml;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        msgXml += "</msg>";
        return msgXml;
    }

    /**
     * 构造药品请求参数
     *
     * @param function
     * @param content
     * @return
     * @throws UnsupportedEncodingException
     */
    private byte[] paramOfDrugs(String function, String content) throws UnsupportedEncodingException {
        ParamHead head = new ParamHead();
        head.setId(WebserviceParam.ID_DRUGS);
        head.setYddwdm(WebserviceParam.YDDWDM_DRUGS);
        head.setFun(function);

        ParamBody body = new ParamBody();
        body.setContent(content);

        RequestParam param = new RequestParam();
        param.setParamHead(head);
        param.setParamBody(body);

        return JAXBUtil.marshalCDATA(param).getBytes("GB2312");
    }

    /**
     * 构造耗材请求参数
     *
     * @param function
     * @param content
     * @return
     * @throws UnsupportedEncodingException
     */
    private byte[] paramOfConsumables(String function, String content) throws UnsupportedEncodingException {
        ParamHead head = new ParamHead();
        head.setId(WebserviceParam.ID_CONSUMABLES);
        head.setYddwdm(WebserviceParam.YDDWDM_CONSUMABLES);
        head.setFun(function);

        ParamBody body = new ParamBody();
        body.setContent(content);

        RequestParam param = new RequestParam();
        param.setParamHead(head);
        param.setParamBody(body);

        return JAXBUtil.marshalCDATA(param).getBytes("GB2312");
    }

    private Map<String, List<OutPutEntity>> formatOutPut(String resp) {
        OutPutResp outPutResp = JAXBUtil.convertToJavaBean(resp, OutPutResp.class);
        Map<String, List<OutPutEntity>> map = new HashMap<>();
        if (outPutResp.getMark().equals("1")) {
            List<OutPutEntity> entities = outPutResp.getMsg();
            if (entities != null && entities.size() != 0) {
                for (OutPutEntity entity : entities) {
                    String id = entity.getPh() + entity.getYdh() + entity.getYy_gysdm();
                    if (map.get(id) == null) {
                        List<OutPutEntity> list = new ArrayList<>();
                        list.add(entity);
                        map.put(id, list);
                    } else {
                        map.get(id).add(entity);
                    }
                }
                return map;
            }
        }
        return null;
    }

    /**
     * 生成流转单号
     *
     * @return
     */
    private String produceRoamNo() {
        ediMapper.correctingRoamNo();
        String prefix = ediMapper.produceRoamPrefix();
        String suffix = ediMapper.produceRoamSuffix();

        return prefix + suffix;
    }

    /**
     * 生成单据编号
     *
     * @return
     */
    private String produceBillNo() {
        return ediMapper.produceIdentityNo("WZ_CG01");
    }

    /**
     * 生成明细编号
     *
     * @return
     */
    private String produceDetailedNo() {
        return ediMapper.produceIdentityNo("WZ_CG02");
    }

    /**
     * 生成库存识别
     *
     * @return
     */
    private String produceStockNo() {
        return ediMapper.produceIdentityNo("WZ_KCSB");
    }
}
